﻿using com.nm.ApiServer;
using com.nm.ApiServer.Attributes;
using com.nm.Attributes;
using george.Data;
using NHibernateVertica;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using com.nm;
using Vertica.Data.VerticaClient;
using VerticaAPI.model;
using com.nm.library;
using com.nm.library.Helper;

namespace VerticaAPI
{
    [Description("日历设置信息")]
    public class CalendarHandler : BaseHandler
    {
        public VerticaDataHelper Helper { get; set; } = new VerticaDataHelper();

        enum DAYTYPE
        {
            平日 = 1,
            周末,
            节日,
            星期日,
            星期一,
            星期二,
            星期三,
            星期四,
            星期五,
            星期六,
        };

        [MustLogin]
        [Description("日期设置列表")]
        [ReturnType(typeof(PaperData<DwCalendarDaysModel.NeceModel>))]
        public ApiResult GetCalendarList([ParamDescription("开始时间")] DateTime BeginDate = default(DateTime), 
            [ParamDescription("结束时间")] DateTime EndDate = default(DateTime), 
            [ParamDescription("查询条件")] string Keys = "",
            [ParamDescription("页码")] int Page = 1,
            [ParamDescription("页数")] int Size = 10)
        {
            try
            {
                if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
                {
                    return Error("该用户不属于任何公司!");
                }
                if(string.IsNullOrEmpty(UserInfo.UserExtrSource))
                {
                    return Error("该用户所在公司没有任何数据源!");
                }
                if (EndDate==Convert.ToDateTime("0001/1/1 0:00:00"))
                {
                    EndDate = DateTime.Now;
                }
                var count = ReturnTotalCalendar(BeginDate, EndDate, Keys);
                var result = PaperData<DwCalendarDaysModel.NeceModel>.Create(count, Size, Page);
                var dt = ReturnCalendarList(BeginDate, EndDate, Page, Size, Keys);
                var list = ModelConvertHelper<DwCalendarDaysModel.NeceModel>.ConvertToModel(dt);
                result.Items = list;
                return Success(result);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }

        /// <summary>
        /// 返回总条数
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        public int ReturnTotalCalendar(DateTime? BeginDate, DateTime? EndDate, string Keys = "")
        {
            try
            {
                var sql = $@"SELECT count(*) FROM ndw.ndw_CalendarDays
where 1=1 
AND CompanyID='{UserInfo.UserCompanyId}' 
AND ExtrSource='{UserInfo.UserExtrSource}'
{(string.IsNullOrEmpty(Keys) ?"":$@" and TypeName like '%{Keys}%' ")} 
{(BeginDate.HasValue? $@" and GregorianDay>='{BeginDate.Value:yyyy-MM-dd}' ":"")} 
{(EndDate.HasValue? $@" and GregorianDay<='{EndDate.Value:yyyy-MM-dd}' ":"")} ";
                var cmd = Helper.GetSqlStringCommand(sql);
                return Convert.ToInt32(Helper.ExecuteScalar(cmd));
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        [MustLogin]
        [Description("最大最小日期设置")]
        [ReturnType(typeof(object))]
        public ApiResult GetMaxMinYear()
        {
            try
            {
                if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
                {
                    return Error("该用户不属于任何公司!");
                }
                if (string.IsNullOrEmpty(UserInfo.UserExtrSource))
                {
                    return Error("该用户所在公司没有任何数据源!");
                }
                var dt = ReturnCalendarList(null, null, null, null);
                var list = ModelConvertHelper<DwCalendarDaysModel.NeceModel>.ConvertToModel(dt);
                var result = new
                {
                    MaxYear = list.Max(d => DateTime.Parse(d.GregorianDay)).Year,
                    MinYear = list.Min(d => DateTime.Parse(d.GregorianDay)).Year,
                };
                return Success(result);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }

        /// <summary>
        /// 返回DataTable
        /// </summary>
        /// <param name="Year"></param>
        /// <returns></returns>
        public DataTable ReturnCalendarList(DateTime? BeginDate, DateTime? EndDate, int? Page, int? Size,
            string Keys = "")
        {
            try
            {
                var sql = $@"select * from (
SELECT *,ROW_NUMBER()OVER(ORDER BY GregorianDay) AS Row FROM ndw.ndw_CalendarDays
where 1=1 
AND CompanyID='{UserInfo.UserCompanyId}'
AND ExtrSource='{UserInfo.UserExtrSource}'
{(string.IsNullOrEmpty(Keys) ? "" : $@" and TypeName like '%{Keys}%' ")} 
{(BeginDate.HasValue ? $@" and GregorianDay>='{BeginDate.Value:yyyy-MM-dd}' " : "")} 
{(EndDate.HasValue ? $@" and GregorianDay<='{EndDate.Value:yyyy-MM-dd}' " : "")} ) table1
where 1=1 
{((Page != null && Size != null) ? $@" and Row BETWEEN ({Page}-1)*{Size}+1 AND {Page}*{Size} " : "")}";
                var cmd = Helper.GetSqlStringCommand(sql);
                return Helper.ExecuteDataTable(cmd);
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        [MustLogin]
        [Description("年历列表")]
        [ReturnType(typeof(IList<DwCalendarDaysModel.NeceModel>))]
        public ApiResult GetFestivalList([ParamDescription("年份")] int Year = -1)
        {
            try
            {
                if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
                {
                    return Error("该用户不属于任何公司!");
                }
                if (string.IsNullOrEmpty(UserInfo.UserExtrSource))
                {
                    return Error("该用户所在公司没有任何数据源!");
                }
                if (Year == -1)
                {
                    Year = DateTime.Now.Year;
                }
                var dt = ReturnFestivalList(Year);
                var list = ModelConvertHelper<DwCalendarDaysModel.NeceModel>.ConvertToModel(dt);
                IList<DwYearHolidayModel.ListModel> result = new List<DwYearHolidayModel.ListModel>();
                for (var i = 0; i < list.Count; i++)
                {
                    var item = new DwYearHolidayModel.ListModel
                    {
                        TypeName = list[i].TypeName,
                        StartDate = list[i].GregorianDay
                    };
                    for (var j = i + 1; j < list.Count; j++)
                    {
                        if (list[i].TypeName == list[j].TypeName)
                        {
                            item.EndDate = list[j].GregorianDay;
                        }
                        else
                        {
                            if (string.IsNullOrEmpty(item.EndDate))
                            {
                                item.EndDate = list[i].GregorianDay;
                            }
                            if (
                                !result.Where(
                                        r =>
                                            r.TypeName == item.TypeName &&
                                            DateTime.Parse(r.EndDate) >= DateTime.Parse(item.StartDate))
                                    .Select(d => d)
                                    .Any())
                            {
                                result.Add(item);
                            }
                            i = j - 1;
                            break;
                        }
                        if (j == list.Count - 1)
                        {
                            if (
                                !result.Where(
                                        r =>
                                            r.TypeName == item.TypeName &&
                                            DateTime.Parse(r.EndDate) >= DateTime.Parse(item.StartDate))
                                    .Select(d => d)
                                    .Any())
                            {
                                result.Add(item);
                            }
                            break;
                        }
                    }
                    if (i == list.Count - 1)
                    {
                        item.EndDate = list[i].GregorianDay;
                        if (
                            !result.Where(
                                r =>
                                    r.TypeName == item.TypeName &&
                                    DateTime.Parse(r.EndDate) >= DateTime.Parse(item.StartDate)).Select(d => d).Any())
                        {
                            result.Add(item);
                        }
                    }
                }
                return Success(result);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }

        public DataTable ReturnFestivalList(int Year)
        {
            try
            {
                var sql = $@"SELECT  cd.*
FROM    ndw.ndw_CalendarDays cd
        INNER JOIN ( SELECT *
                     FROM   ndw.ndw_YearHoliday
                     WHERE  CompanyID = '{UserInfo.UserCompanyId}'
                            AND ExtrSource = '{UserInfo.UserExtrSource}'
                   ) yh ON cd.GregorianDay = yh.GregorianDay
                           AND cd.ExtrSource = yh.ExtrSource
                           AND cd.CompanyID = yh.CompanyID
WHERE   cd.YearV = '{Year}'
        AND cd.CompanyID = '{UserInfo.UserCompanyId}'
        AND cd.ExtrSource = '{UserInfo.UserExtrSource}'
ORDER BY cd.GregorianDay ";
                var cmd = Helper.GetSqlStringCommand(sql);
                return Helper.ExecuteDataTable(cmd);
            }
            catch(Exception ex)
            {
                throw(ex);
            }
        }

        [JsonType]
        [MustLogin]
        [Description("修改节假日信息")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult ModifyCalendar([ParamDescription("节日信息")] DwYearHolidayModel.InitModel param)
        {
            const string sqlDeleteYearHoliday = @"DELETE FROM  ndw.ndw_YearHoliday WHERE HolidayYearv = '{0}' AND CompanyID = '{1}' AND ExtrSource = '{2}' ";
            const string sqlUpdateCalendarDays = @"UPDATE  ndw.ndw_CalendarDays
SET     DayType = @DayType ,
        TypeName = @TypeName ,
        SuppleRate = @SuppleRate
WHERE   GregorianDay = @GregorianDay
        AND CompanyID = @CompanyID
        AND ExtrSource = @ExtrSource";
            try
            {
                if (param == null) return Error("参数对象为空");
                if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
                {
                    return Error("该用户不属于任何公司!");
                }
                if (string.IsNullOrEmpty(UserInfo.UserExtrSource))
                {
                    return Error("该用户所在公司没有任何数据源!");
                }
                var gvHandler = new DwGlobalVariableHandler();
                var gvList = gvHandler.GetGlobalVariableChildrenList("周末系数");
                IList<DwYearHolidayModel.CreatModel> listHoliday = new List<DwYearHolidayModel.CreatModel>();
                var dayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.平日);
                var suppleRate = (int)DAYTYPE.平日;
                var et = DateTime.Now;
                var st = DateTime.Now;
                var oet = DateTime.Now;
                var ost = DateTime.Now;
                var cmdList = new List<CommandInfo>()
                {
                    new CommandInfo()
                    {
                        CommandText =
                            string.Format(sqlDeleteYearHoliday,
                                DateTime.Parse(string.IsNullOrEmpty(param.list.First().StartDate)
                                    ? param.list.First().OldStartDate
                                    : param.list.First().StartDate).Year,UserInfo.UserCompanyId,UserInfo.UserExtrSource),
                    }
                };
                if (param.list != null)
                {
                    foreach (var item in param.list)
                    {
                        if (!string.IsNullOrEmpty(item.OldStartDate) && !string.IsNullOrEmpty(item.OldEndDate))
                        {
                            oet = DateTime.Parse(item.OldEndDate);
                            ost = DateTime.Parse(item.OldStartDate);
                            for (var j = 0; j <= oet.Subtract(ost).Days; j++)
                            {
                                switch (ost.AddDays(j).DayOfWeek)
                                {
                                    case DayOfWeek.Saturday:
                                    case DayOfWeek.Sunday:
                                        dayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.周末);
                                        var zmxs = gvList
                                            .FirstOrDefault(d => d.dictName == "周末系数");
                                        if (zmxs != null)
                                            suppleRate = Convert.ToInt32(zmxs.dictValue);
                                        break;
                                    case DayOfWeek.Friday:
                                        dayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.平日);
                                        var zwxs = gvList
                                            .FirstOrDefault(d => d.dictName == "周五系数");
                                        if (zwxs != null)
                                            suppleRate = Convert.ToInt32(zwxs.dictValue);
                                        break;
                                    default:
                                        dayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.平日);
                                        suppleRate = (int)DAYTYPE.平日;
                                        break;
                                }
                                var vpcUpdateEm = new VerticaParameter[]
                                {
                                    new VerticaParameter("@DayType", dayType),
                                    new VerticaParameter("@TypeName", null),
                                    new VerticaParameter("@SuppleRate", suppleRate),
                                    new VerticaParameter("@GregorianDay", ost.AddDays(j).ToString("yyyy-MM-dd")),
                                    new VerticaParameter("@CompanyID", UserInfo.UserCompanyId),
                                    new VerticaParameter("@ExtrSource", UserInfo.UserExtrSource),
                                };
                                var upCmd1 = new CommandInfo()
                                {
                                    CommandText = sqlUpdateCalendarDays,
                                    Parameters = vpcUpdateEm,
                                };
                                cmdList.Add(upCmd1);
                            }
                        }
                        if (string.IsNullOrEmpty(item.StartDate) && string.IsNullOrEmpty(item.EndDate)) continue;
                        et = DateTime.Parse(item.EndDate);
                        st = DateTime.Parse(item.StartDate);
                        for (var i = 0; i <= et.Subtract(st).Days; i++)
                        {
                            var holiday = new DwYearHolidayModel.CreatModel
                            {
                                CompanyID = UserInfo.UserCompanyId,
                                ExtrSource = UserInfo.UserExtrSource,
                                HolidayYearv = st.AddDays(i).Year,
                                TypeName = item.TypeName,
                                HolidayNum = i + 1,
                                GregorianDay = st.AddDays(i).ToString("yyyy-MM-dd")
                            };
                            listHoliday.Add(holiday);
                        }
                        for (var k = 0; k <= et.Subtract(st).Days; k++)
                        {
                            var vpcUpdate = new VerticaParameter[]
                            {
                                new VerticaParameter("@DayType", Enum.GetName(typeof(DAYTYPE), DAYTYPE.节日)),
                                new VerticaParameter("@TypeName", item.TypeName),
                                new VerticaParameter("@SuppleRate", VerticaType.Numeric, null),
                                new VerticaParameter("@GregorianDay", st.AddDays(k).ToString("yyyy-MM-dd")),
                                new VerticaParameter("@CompanyID", UserInfo.UserCompanyId),
                                new VerticaParameter("@ExtrSource", UserInfo.UserExtrSource),
                            };
                            var upCmd2 = new CommandInfo()
                            {
                                CommandText = sqlUpdateCalendarDays,
                                Parameters = vpcUpdate,
                            };
                            cmdList.Add(upCmd2);
                        }
                    }
                }
                var dt = DataTableHelper.LinqToDataTable(listHoliday);
                Helper.ExecuteSqlTran(cmdList, dt, "ndw.ndw_YearHoliday");
                return Success(0);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }

        //public ApiResult DeleteCalendar([ParamDescription("节日信息")] object param)
        //{
        //    if (param == null) return Error("参数对象为空");
        //    var sqlDeleteYearHoliday = @"DELETE FROM  dw.dw_YearHoliday WHERE GregorianDay between @StartDate AND @EndDate";
        //    var sqlUpdateCalendarDays = @"where 1=1 ";
        //    var resultDelete = Helper.Perform(sqlDeleteYearHoliday);
        //    var vpcUpdate = new VerticaParameterCollection
        //    {
        //        new VerticaParameter(),
        //    };
        //    var resultUpdate = Helper.Perform(vpcUpdate, sqlUpdateCalendarDays);
        //    return NotDoneError();
        //}

        [MustLogin]
        [Description("生成日历")]
        [ReturnType(typeof(int), "0-成功")]
        public ApiResult CreateCalendarDays([ParamDescription("年份")] int Year = -1)
        {
            try
            {
                if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
                {
                    return Error("该用户不属于任何公司!");
                }
                if (string.IsNullOrEmpty(UserInfo.UserExtrSource))
                {
                    return Error("该用户所在公司没有任何数据源!");
                }
                if (Year == -1)
                {
                    Year = DateTime.Now.Year;
                }
                var cdt = ReturnCalendarList(null, null, null, null);
                var cdList = ModelConvertHelper<DwCalendarDaysModel.NeceModel>.ConvertToModel(cdt);
                if (cdList.Any(r => r.YearV == (long)Year))
                {
                    return Error("该年份已经存在！");
                }
                if (cdList.Max(d => d.YearV).HasValue)
                {
                    if (cdList.Max(d => d.YearV) + 1 != Year)
                    {
                        return Error("该年份上一年数据还没生成！");
                    }
                }
                else
                {
                    if (Year != DateTime.Now.Year)
                    {
                        return Error("该年份上一年数据还没生成！");
                    }
                }
                var sqlGet = @"where 1=1 ";
                var gvList = new DwGlobalVariableHandler().GetGlobalVariableChildrenList("周末系数");
                if (gvList == null) return Error("该公司周末系数还没设置！");
                var zwxs = gvList
                    .FirstOrDefault(d => d.dictName == "周五系数");
                if (zwxs == null) return Error("该公司周五系数还没设置！");
                var zmxs = gvList
                    .FirstOrDefault(d => d.dictName == "周末系数");
                if (zmxs == null) return Error("该公司周末系数还没设置！");
                IList<DwCalendarDaysModel.CreatModel> list = new List<DwCalendarDaysModel.CreatModel>();
                for (var i = 0; i < (DateTime.IsLeapYear(Year) ? 366 : 365); i++)
                {
                    var d = new DateTime(Year, 1, 1).AddDays(i);
                    var item = new DwCalendarDaysModel.CreatModel
                    {
                        YearV = Year,
                        MonthV = d.Month,
                        Weekv = GetWeekOfYear(d),
                        LunarDay = GetChineseDateTime(d),
                        GregorianDay = d.ToString("yyyy-MM-dd"),
                        DayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.平日),
                        SuppleRate = (int) DAYTYPE.平日,
                        CompanyID = UserInfo.UserCompanyId,
                        ExtrSource = UserInfo.UserExtrSource,
                        EtlDate = DateTime.Now,
                        LoadTime = DateTime.Now,
                    };
                    switch (d.DayOfWeek)
                    {
                        case DayOfWeek.Sunday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期日);
                            item.DayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.周末);
                            item.SuppleRate = Convert.ToDecimal(zmxs.dictValue);
                            break;
                        case DayOfWeek.Monday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期一);
                            break;
                        case DayOfWeek.Tuesday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期二);
                            break;
                        case DayOfWeek.Wednesday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期三);
                            break;
                        case DayOfWeek.Thursday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期四);
                            break;
                        case DayOfWeek.Friday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期五);
                            item.SuppleRate = Convert.ToDecimal(zwxs.dictValue);
                            break;
                        case DayOfWeek.Saturday:
                            item.WeekDayNum = Enum.GetName(typeof(DAYTYPE), DAYTYPE.星期六);
                            item.DayType = Enum.GetName(typeof(DAYTYPE), DAYTYPE.周末);
                            item.SuppleRate = Convert.ToDecimal(zmxs.dictValue);
                            break;
                        default:
                            break;
                    }
                    list.Add(item);
                }
                var dt = DataTableHelper.LinqToDataTable(list);
                Helper.BulkCopy(dt, "ndw.ndw_CalendarDays");
                return Success(0);
            }
            catch (Exception ex)
            {
                return Error(ex.Message);
            }
        }

        /// <summary>
        /// 获取指定日期，在为一年中为第几周
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static int GetWeekOfYear(DateTime dt)
        {
            var gc = new GregorianCalendar();
            var weekOfYear = gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
            return weekOfYear;
        }

        /// <summary>
        /// 获取指定周数的开始日期和结束日期，开始日期为周日
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="index">周数</param>
        /// <param name="first">当此方法返回时，则包含参数 year 和 index 指定的周的开始日期的 System.DateTime 值；如果失败，则为 System.DateTime.MinValue。</param>
        /// <param name="last">当此方法返回时，则包含参数 year 和 index 指定的周的结束日期的 System.DateTime 值；如果失败，则为 System.DateTime.MinValue。</param>
        /// <returns></returns>
        /// Writer：梁家健
        /// Create Date：2017-03-15
        public void GetDaysOfWeeks(int year, int index, out DateTime first, out DateTime last)
        {
            try
            {
                first = DateTime.MinValue;
                last = DateTime.MinValue;
                if (year < 1700 || year > 9999)
                {
                    //"年份超限"
                    throw (new Exception("年份超限"));
                }
                if (index < 1 || index > 53)
                {
                    //"周数错误"
                    throw (new Exception("周数错误"));
                }
                DateTime startDay = new DateTime(year, 1, 1);  //该年第一天
                DateTime endDay = new DateTime(year + 1, 1, 1).AddMilliseconds(-1);
                int dayOfWeek = 7;
                if (Convert.ToInt32(startDay.DayOfWeek.ToString("d")) > 0)
                    dayOfWeek = Convert.ToInt32(startDay.DayOfWeek.ToString("d"));  //该年第一天为星期几
                first = startDay.AddDays((0 - dayOfWeek) + index * 7); //index周的起始日期
                last = first.AddDays(6);
                if (first > endDay)  //startDayOfWeeks不在该年范围内
                {
                    //"输入周数大于本年最大周数";
                    throw (new Exception("输入周数大于本年最大周数"));
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }

        /// <summary>
        /// 求某年有多少周
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        public static int GetYearWeekCount(int year)
        {
            var fDt = new DateTime(year, 1, 1);
            var countDay = fDt.AddYears(1).AddDays(-1).DayOfYear;
            if (fDt.DayOfWeek==DayOfWeek.Sunday)
            {
                var countWeek = countDay / 7 + 1;
                return countWeek;
            }
            else
            {
                var countWeek = countDay / 7 + 2;
                return countWeek;
            }
        }

        #region 获取农历
        /// <summary>   
        /// 实例化一个  ChineseLunisolarCalendar       
        /// </summary>  
        private static ChineseLunisolarCalendar ChineseCalendar = new ChineseLunisolarCalendar();  
        /// <summary>  
        /// 十天干  
        /// </summary>  
        private static string[] tg = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸" };  
        /// <summary>  
        ///  十二地支  
        ///  </summary>  
        private static string[] dz = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" };  
        /// <summary>  
        /// 十二生肖  
        /// </summary>  
        private static string[] sx = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" };
        /// <summary>
        /// 中文数字
        /// </summary>
        private static string[] dx = { "〇" , "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        /// <summary>  
        ///  返回农历天干地支年  
        ///   </summary>  
        ///    <param name="year">农历年</param>  
        ///    <returns></returns>  
        public static string GetLunisolarYear(int year)  
        {  
            if (year > 3)  
            {  
                int tgIndex = (year - 4) % 10;  
                int dzIndex = (year - 4) % 12;  
                return string.Concat(tg[tgIndex], dz[dzIndex], "[", sx[dzIndex], "]");  
            }  
            throw new ArgumentOutOfRangeException("无效的年份!");  
        }
        /// <summary>
        /// 返回中文数字
        /// </summary>
        /// <param name="year"></param>
        /// <returns></returns>
        public static string GetChineseNum(int year)
        {
            var str = year.ToString();
            var result = "";
            foreach (var t in str)
            {
                var index = int.Parse(t.ToString());
                result += dx[index];
            }
            return result;
        }

        /// <summary>  
        /// 农历月  
        /// </summary>  
        /// <returns></returns>  
        private static string[] months = { "正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二" };  
        /// <summary>  
        /// 农历日  
        /// </summary>  
        private static string[] days1 = { "初", "十", "廿", "三" };  
        /// <summary>  
        ///  农历日  
        /// </summary>  
        private static string[] days = { "一", "二", "三", "四", "五", "六", "七", "八", "九", "十" };  
        /// <summary>  
        /// 返回农历月  
        /// </summary>  
        /// <param name="month">月份</param>  
        /// <returns></returns>  
        public static string GetLunisolarMonth(int month)  
        {  
            if (month < 13 && month > 0)  
            {  
                return months[month - 1];  
            }  
            throw new ArgumentOutOfRangeException("无效的月份!");  
        }  
        /// <summary>  
        /// 返回农历日  
        /// </summary>  
        /// <param name="day">天</param>  
        /// <returns></returns>  
        public static string GetLunisolarDay(int day)  
        {  
            if (day > 0 && day < 32)  
            {  
                if (day != 20 && day != 30)  
                {  
                    return string.Concat(days1[(day - 1) / 10], days[(day - 1) % 10]);  
                }  
                else  
                {  
                    return string.Concat(days[(day - 1) / 10], days1[1]);  
                }  
            }  
            throw new ArgumentOutOfRangeException("无效的日!");  
        }  
  
        /// <summary>   
        /// 根据公历获取农历日期  
        /// </summary>  
        /// <param name="datetime">公历日期</param>  
        /// <returns></returns>  
        public static string GetChineseDateTime(DateTime datetime)  
        {  
            //农历的年月日  
            int year = ChineseCalendar.GetYear(datetime);  
            int month = ChineseCalendar.GetMonth(datetime);  
            int day = ChineseCalendar.GetDayOfMonth(datetime);  
            //获取闰月， 0 则表示没有闰月   
            int leapMonth = ChineseCalendar.GetLeapMonth(year);  
            bool isleap = false;  
            if (leapMonth > 0)  
            {  
                if (leapMonth == month)  
                {  
                    //闰月       
                    isleap = true;  
                    month--;  
                }  
                else if (month > leapMonth)  
                {  
                    month--;  
                }  
            }  
            return string.Concat(GetChineseNum(year), "年", isleap ? "闰" : string.Empty, GetLunisolarMonth(month), "月", GetLunisolarDay(day));  
        }
        #endregion


        [MustLogin]
        [Description("获取今年内所有节日信息(首页图表专用)")]
        [ReturnType(typeof(IList<DwYearHolidayModel.ChartModel>))]
        public ApiResult GetAllHolidayByYear()
        {
            if (string.IsNullOrEmpty(UserInfo.UserCompanyId))
            {
                return Error("该用户不属于任何公司!");
            }
            if (string.IsNullOrEmpty(UserInfo.UserExtrSource))
            {
                return Error("该用户所在公司没有任何数据源!");
            }
            var year = DateTime.Now.Year.ToString();
            var sql = $@" select TypeName,max(HolidayNum) as 'Duration',min(GregorianDay) as 'BeginDate' 
from ndw.ndw_YearHoliday where HolidayYearv = {year}
AND CompanyID='{UserInfo.UserCompanyId}'
AND ExtrSource='{UserInfo.UserExtrSource}'
group by TypeName; ";
            var cmd = Helper.GetSqlStringCommand(sql);
            var dt = Helper.ExecuteDataTable(cmd);
            var list = ModelConvertHelper<DwYearHolidayModel.HolidayModel>.ConvertToModel(dt).OrderBy(d => d.BeginDate).ToList();

            try
            {
                if (list != null && list.Count > 0)
                {
                    var tmpModel = list.Where(x => !(Convert.ToDateTime(x.BeginDate + " 00:00:00") < DateTime.Now))
                        .OrderBy(x => Convert.ToDateTime(x.BeginDate + " 00:00:00"))
                        .Take(1).FirstOrDefault();
                    if (tmpModel != null)
                    {
                        tmpModel.IsNext = true;
                    }
                }
            }
            catch (Exception e)
            {
                //只是为了防止各种可能出现的异常导致接口返回失败，这里不具体处理任何异常信息
            }
            var data = new DwYearHolidayModel.ChartModel() { Year = year, List = list };
            return Success(data);
        }
    }
}
